<?php

namespace Acme\FileManagerBundle\Services;

use Acme\FileManagerBundle\Entity\File;
use Acme\FileManagerBundle\Entity\Directory;
use Acme\FileManagerBundle\Entity\BaseFile;

class FileManager implements IFileManager
{
    private $m_rootDirectory;
    
    public function setRootDirectory($path)
    {
        $this->m_rootDirectory = $path;
    }
    
    public function getRealPath($path)
    {
        return $this->m_rootDirectory . '/' . $path;
    }
    
    public function getRelativePath($path)
    {
        return \str_replace($this->m_rootDirectory, '', $path);
    }
    
    public function readFile($path)
    {
        $realPath = $this->getRealPath($path);
        
        if (!\file_exists($realPath) || is_dir($realPath)) {
            throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
        }
        
        $fileName = \basename($path);
        $content = \file_get_contents($realPath);
        
        $file = new File;
        $file->setName($fileName);
        $file->setPath($realPath);
        $file->setRelativePath($this->getRelativePath($realPath));
        $file->setContent($content);
        
        return $file;
    }
    
    public function createDirectory(Directory $directory)
    {
        $path = $this->getRealPath($directory->getRelativePath()) . '/' . $directory->getName();
        
        if (\is_dir($path)) {
            throw new \Exception('Folder already exists');
        }
        
        if (!\mkdir($path, \octdec($directory->getPermissions()))) {
            throw new \Exception('Cound not create folder!');
        }
    }
    
    public function deleteFile($path)
    {
        $realPath = $this->getRealPath($path);
        
        if (!file_exists($realPath)) {
            throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
        }
        
        if (!is_dir($realPath))
        {
            \unlink($realPath);
            
            return;
        }
        
        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($realPath), \RecursiveIteratorIterator::CHILD_FIRST);
        
        foreach ($iterator as $file)
        {
            if ($file->isDir())
            {
                \rmdir($file->__toString());
            }
            else
            {
                \unlink($file->__toString());
            }
        }
        
        \rmdir($realPath);
    }
    
    public function listDirectory($path)
    {
        $files = array();
        $realPath = $this->getRealPath($path);
        
        if (!\is_dir($realPath)) {
            throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
        }
        
        $iterator = new \RecursiveDirectoryIterator($realPath, \FilesystemIterator::SKIP_DOTS);
        
        foreach ($iterator as $file)
        {
            $fileTmp = false;
            
            $realPath = \str_replace('\\', '/', $file->__toString());
            $filePath = $this->getRelativePath($realPath);
            $fileName = \basename($realPath);
            
            $fileTmp = (\is_dir($realPath)) ? new Directory : new File;
            
            $fileTmp->setName($fileName);
            $fileTmp->setPath($realPath);
            $fileTmp->setRelativePath($filePath);
            
            $files[] = $fileTmp;
        }
        
        // Сортировка - Сначала папки в алфавит. порядке
        usort($files, function($left, $right) {
            
            $leftType = $left->getType();
            $rightType = $right->getType();
            
            if ($leftType === $rightType)
            {
                return \strnatcmp($left->getName(), $right->getName());
            }
            
            return ($leftType === 'directory') ? -1 : 1;
            
        });
        
        return $files;
    }
}